﻿//---------------------------------------------------------
//Create By Kevin Xi @ 2011-12-14
//
//Contact Me kevinxi10@163.com
//
//---------------------------------------------------------
function $Animation(element,parameters){
/*
    element: 请传入html对象或者其名称
    parameters:{"envent":"click","animation":[{"Opaccity":"0"},{"size":" width height"}],"mode":" in or out" }
*/
    if(element && typeof(element) =="string"){
        this._element=document.getElementById(element);
    }
    else if(element && typeof(element) == "object"){
        this._element = element;
    }
    else{
        throw "必须传入html对象或其 id ！";
    }
    
    if(parameters && typeof(parameters) != "object"){
        throw "参数必须以对象的形式传入 ！";
    }
    
    for(parameter in parameters){
        this[parameter] = parameters[parameter];
    }
    
    var self = this;
    
    if(this._element.addEventListener){
        this._element.addEventListener(this.eventType,function(event){self.handleEvent(event);},false);
    }
    this.currentState = this.initialState;
}
$Animation.prototype={
    eventType:"",
    animations:{},
    mode:"in",
    Opacity:{},
    Size:{},
    currentState:null,
    currentTimer:null,
    currentTicker:null,
    
    initialState:"InActive",
    handleEvent:function(event){
        var actionTransitionFunction = this.actionTransitionFunctions[this.currentState][event.type];
        if (!actionTransitionFunction) actionTransitionFunction = this.unexpectedEvent;
        var nextState = actionTransitionFunction.call(this, event);
        if (!nextState) nextState = this.currentState;
        //if (this.trace) trace("'" + event.type + "' event caused transition from '" + this.currentState + "' state to '" + nextState + "' state");
        if (!this.actionTransitionFunctions[nextState]) nextState = this.undefinedState(event, nextState);
        this.currentState = nextState;
    },
    unexpectedEvent: function(event) { 
        this.cancelTimer();
        this.cancelTicker();
        this.deleteTooltip();
        alert("Animation handled unexpected event '" + event.type + "' in state '" + this.currentState + "' for id='" + this.htmlElement.id + "' running browser " + window.navigator.userAgent);
        return this.initialState; 
    },
    undefinedState: function(event, state) {
        this.cancelTimer();
        this.cancelTicker();
        this.deleteTooltip();
        alert("FadingTooltip transitioned to undefined state '" + state + "' from state '" + this.currentState + "' due to event '" + event.type + "' from HTML element id='" + this.htmlElement.id + "' running browser " + window.navigator.userAgent);
        return this.initialState; 
    },  
    actionTransitionFunctions: { 
    
        Inactive: {
        
            mouseover: function(event) { 
                this.cancelTimer();
                this.saveCursorPosition(event.clientX, event.clientY);
                this.startTimer(this.pauseTime*1000);
                return "Pause";
            },
            
            mousemove: function(event) { 
                return this.doActionTransition("Inactive", "mouseover", event);
            },
            
            mouseout: function(event) {
                return this.currentState; // do nothing
            }
        }, // end of  Inactive
        
        Pause: {
            
            mousemove: function(event) { 
                return this.doActionTransition("Inactive", "mouseover", event);
            },
            
            mouseout: function(event) { 
                this.cancelTimer();
                return "Inactive";
            },
            
            timeout: function(event) { 
                this.cancelTimer();
                this.createTooltip();
                if (this.fadeinTime>0) { 
                    this.startTicker(1000/this.fadeRate);
                    return "FadeIn";
                } else {
                    this.fadeTooltip(+this.tooltipOpacity);
                    this.startTimer(this.displayTime*1000);
                    return "Display";
                }
            }
        }, // end of  Pause
        
        
        FadeIn: {
            
            mousemove: function(event) { 
                return this.doActionTransition("Display", "mousemove", event);
            },
            
            mouseout: function(event) { 
                return "FadeOut";
            },
            
            timetick: function(event) {
                this.fadeTooltip(+this.tooltipOpacity/(this.fadeinTime*this.fadeRate));
                if (this.currentOpacity>=this.tooltipOpacity) {
                    this.cancelTicker();
                    this.startTimer(this.displayTime*1000);
                    return "Display";
                }
                return this.CurrentState;
            }
        }, // end of  FadeIn
        

        Display: {

            mousemove: function(event) { 
                this.moveTooltip(event.clientX, event.clientY);
                return this.currentState;
            },

            mouseout: function(event) { 
                return this.doActionTransition("Display", "timeout", event);
            },

            timeout: function(event) { 
                this.cancelTimer();
                if (this.fadeoutTime>0) { 
                    this.startTicker(1000/this.fadeRate);
                    return "FadeOut";
                } else {
                    this.deleteTooltip();
                    return "Inactive";
                }
            }
        }, // end of Display

        FadeOut: {

            mouseover: function(event) { 
                this.moveTooltip(event.clientX, event.clientY);
                return "FadeIn";
            },

            mousemove: function(event) { 
                return this.doActionTransition("Display", "mousemove", event);
            },
            mouseout: function(event) { 
                return this.currentState; // do nothing
            }, 

            timetick: function(event) { 
                this.fadeTooltip(-this.tooltipOpacity/(this.fadeoutTime*this.fadeRate));
                if (this.currentOpacity<=0) {
                    this.cancelTicker();
                    this.deleteTooltip();
                    return "Inactive";
                }
                return this.currentState;
            }
        } // end of FadeOut
    }, //end of actionTransitionFunctions
     doActionTransition: function(anotherState, anotherEventType, event) {
         return this.actionTransitionFunctions[anotherState][anotherEventType].call(this,event);
    },
    startTimer: function(timeout) { 
        var self = this;
        this.currentTimer = setTimeout(function() { self.handleEvent( { type: "timeout" } ); }, timeout);
    },
    cancelTimer: function() { 
        if (this.currentTimer) clearTimeout(this.currentTimer);
        this.currentTimer = null;
    },
    startTicker: function(interval) { 
        var self = this;
        this.currentTicker = setInterval(function() { self.handleEvent( { type: "timetick" } ); }, interval);
    },
    cancelTicker: function() {
        if (this.currentTicker) clearInterval(this.currentTicker);
        this.currentTicker = null; 
    },
    saveCursorPosition: function(x, y) {
        this.lastCursorX = x;
        this.lastCursorY = y;
    },
    fadeTooltip: function(opacityDelta) { 
        
        this.currentOpacity = Math.round((this.currentOpacity + opacityDelta)*1000000)/1000000; 
                
        if (this.currentOpacity<0) this.currentOpacity = 0;
        if (this.currentOpacity>this.tooltipOpacity) this.currentOpacity = this.tooltipOpacity;
        
        this.tooltipDivision.style.opacity = this.currentOpacity;
        if (this.tooltipDivision.filters) this.tooltipDivision.filters.item('alpha').opacity = 100*this.currentOpacity; // for MSIE only
    }
    
}